package com.pcbly.web.components.utils.template.dwr;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.io.FileUtils;

import com.pcbly.web.components.utils.template.TemplateModel;

public class ModelDwr {
	public final static String packName = "com.pcbly.web.components.utils.template";

	public Field[] fields;

	public TemplateModel model;

	private boolean single = false;

	private boolean print = false;

	private List<String> actionXMLString = new ArrayList<String>();

	public boolean isPrint() {
		return print;
	}

	public void setPrint(boolean print) {
		this.print = print;
	}

	public boolean isSingle() {
		return single;
	}

	public void setSingle(boolean single) {
		this.single = single;
	}

	public List<String> getActionXMLString() {
		return actionXMLString;
	}

	public void setActionXMLString(List<String> actionXMLString) {
		this.actionXMLString = actionXMLString;
	}

	public Field[] getFields() {
		return fields;
	}

	public void setFields(Field[] fields) {
		this.fields = fields;
	}

	public TemplateModel getModel() {
		return model;
	}

	public void setModel(TemplateModel model) {
		this.model = model;
	}

	protected String dwrXmlPath() {
		String packageName = "com.pcbly.web.action." + model.getEntityL();
		String name = "applicationContext-dwr.xml";
		return model.getFilePath(packageName, name);
	}

	protected String dwrNotSingleXmlPath() {
		String packageName = "com.pcbly.web.action." + model.getEntityL();
		String name = model.getFirstEntityL() + "-applicationContext-dwr.xml";
		return model.getFilePath(packageName, name);
	}

	protected String fieldReplace(String content, Field[] tempFields) {
		StringBuilder fields = new StringBuilder();
		for (Field field : tempFields) {
			if (field == null) {
				break;
			}
			fields.append("<dwr:include method=\"");
			fields.append(field.getName());
			fields.append("\"/>\r\n");
		}
		content = content.replaceAll("\\#\\{fields\\}", fields.toString());
		return content;
	}

	protected String replaceHead(String content, String replace, String old) {
		content = content.replaceAll(old, replace);
		return content;
	}

	public void printMessage() {
		for (String string : actionXMLString) {
			System.out.println(string);
		}
	}

	String readTpl(File tpl) {
		return readTpl(tpl, "UTF-8");
	}

	String readTpl(File tpl, String charset) {
		String content = null;
		try {
			content = FileUtils.readFileToString(tpl, charset);
		} catch (IOException e) {
			System.out.println("read file faild. " + e.getMessage());
		}
		return content;
	}

	private String initHeadDwr() {
		StringBuilder sb = new StringBuilder();
		sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n");
		sb
				.append("<beans xmlns=\"http://www.springframework.org/schema/beans\"\r\n");
		sb.append("	xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ");
		sb
				.append(" xmlns:aop=\"http://www.springframework.org/schema/aop\"\r\n");
		sb.append("	xmlns:util=\"http://www.springframework.org/schema/util\"");
		sb
				.append(" xmlns:dwr=\"http://www.directwebremoting.org/schema/spring-dwr\"\r\n");
		sb.append("	xsi:schemaLocation=\"\r\n");
		sb.append("http://www.springframework.org/schema/aop ");
		sb
				.append("http://www.springframework.org/schema/aop/spring-aop-2.5.xsd\r\n");
		sb.append("http://www.springframework.org/schema/beans ");
		sb
				.append(" http://www.springframework.org/schema/beans/spring-beans-2.5.xsd\r\n");
		sb.append("http://www.springframework.org/schema/util ");
		sb
				.append("http://www.springframework.org/schema/util/spring-util-2.5.xsd\r\n");
		sb.append("http://www.directwebremoting.org/schema/spring-dwr ");
		sb
				.append("http://www.directwebremoting.org/schema/spring-dwr-2.0.xsd\"\r\n");
		sb.append("	default-autowire=\"no\" default-init-method=\"init\"\r\n");
		sb.append("	default-destroy-method=\"destroy\">\r\n");
		sb.append("	<dwr:configuration>\r\n");
		sb.append("		<!--action-->\r\n");
		sb.append("		<!--convert-->\r\n");
		sb.append("	</dwr:configuration>\r\n");
		sb.append("</beans>\r\n");
		return sb.toString();
	}

	private void exeSingle() throws Exception {
		String pathXml = dwrXmlPath();
		if (print) {
			actionXMLString.add("<import resource=\"" + pathXml + "\"/>");
		} else {
			File file = new File(pathXml);

			String content = "";
			if (!file.exists()) {
				file.createNewFile();
				content = initHeadDwr();
			} else {
				content = readTpl(file);
			}

			String name = "dwr-action.txt";
			StringBuilder sb = new StringBuilder();

			pathXml = model.getFilePath(packName, name);
			File fileXML = new File(pathXml);
			pathXml = model.readTpl(fileXML);
			// pathXml = fieldReplace(pathXml, fields);
			content = replaceHead(content, pathXml, "		<!--action-->");

			name = "dwr-convert.txt";
			pathXml = model.getFilePath(packName, name);
			fileXML = new File(pathXml);
			pathXml = model.readTpl(fileXML);
			pathXml = fieldReplace(pathXml, fields);
			pathXml = replaceHead(content, pathXml, "		<!--convert-->");
			sb.append(pathXml);
			FileUtils.writeStringToFile(file, sb.toString(), "UTF-8");
			if (file != null) {
				file = null;
			}
			if (fileXML != null) {
				fileXML = null;
			}
		}
	}

	private void executeNotSingle() throws Exception {
		String pathXml = dwrNotSingleXmlPath();
		if (print) {
			actionXMLString.add("<import resource=\"" + pathXml + "\"/>");
		} else {
			File file = new File(pathXml);
			String name = "dwr.txt";
			StringBuilder sb = new StringBuilder();

			pathXml = model.getFilePath(packName, name);
			File fileXML = new File(pathXml);
			pathXml = model.readTpl(fileXML);
			pathXml = fieldReplace(pathXml, fields);
			sb.append(pathXml);
			FileUtils.writeStringToFile(file, sb.toString(), "UTF-8");
			if (file != null) {
				file = null;
			}
			if (fileXML != null) {
				fileXML = null;
			}
		}
	}

	public void execute() {
		try {
			if (single) {
				exeSingle();
			} else {
				executeNotSingle();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
